}
static void
-gdk_offscreen_window_queue_translation (GdkWindow *window,
- GdkGC *gc,
- cairo_region_t *area,
- gint dx,
- gint dy)
+gdk_offscreen_window_translate (GdkWindow *window,
+ cairo_region_t *area,
+ gint dx,
+ gint dy)
{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ /* Can't use gdk_cairo_create here due to clipping */
+ surface = _gdk_drawable_ref_cairo_surface (window);
+ cr = cairo_create (surface);
+ cairo_surface_destroy (surface);
+
+ area = cairo_region_copy (area);
+
+ gdk_cairo_region (cr, area);
+ cairo_clip (cr);
+
+ /* NB: This is a self-copy and Cairo doesn't support that yet.
+ * So we do a litle trick.
+ */
+ cairo_push_group (cr);
+
+ gdk_cairo_set_source_pixmap (cr, window, dx, dy);
+ cairo_paint (cr);
+
+ cairo_pop_group_to_source (cr);
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+
+ _gdk_window_add_damage (window, area);
}
/**
iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region;
iface->set_static_gravities = gdk_offscreen_window_set_static_gravities;
iface->queue_antiexpose = gdk_offscreen_window_queue_antiexpose;
- iface->queue_translation = gdk_offscreen_window_queue_translation;
+ iface->translate = gdk_offscreen_window_translate;
iface->get_root_coords = gdk_offscreen_window_get_root_coords;
iface->get_deskrelative_origin = gdk_offscreen_window_get_deskrelative_origin;
iface->get_device_state = gdk_offscreen_window_get_device_state;
cairo_region_t *dest_region, /* In impl window coords */
int dx, int dy)
{
- GdkGC *tmp_gc;
- GdkRectangle copy_rect;
- GdkWindowObject *private;
GdkWindowImplIface *impl_iface;
- /* We need to get data from subwindows here, because we might have
- * shaped a native window over the moving region (with bg none,
- * so the pixels are still there). In fact we might need to get data
- * from overlapping native window that are not children of this window,
- * so we copy from the toplevel with INCLUDE_INFERIORS.
- */
- private = impl_window;
- while (!gdk_window_is_toplevel (private))
- {
- dx -= private->parent->abs_x + private->x;
- dy -= private->parent->abs_y + private->y;
- private = gdk_window_get_impl_window (private->parent);
- }
- tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private);
-
- cairo_region_get_extents (dest_region, ©_rect);
- gdk_gc_set_clip_region (tmp_gc, dest_region);
-
- /* The region area is moved and we queue translations for all expose events
- to the source area that were sent prior to the copy */
- cairo_region_translate (dest_region, -dx, -dy); /* Move to source region */
- impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
-
- impl_iface->queue_translation ((GdkWindow *)impl_window,
- tmp_gc,
- dest_region, dx, dy);
+ impl_iface = GDK_WINDOW_IMPL_GET_IFACE (impl_window->impl);
- gdk_draw_drawable (impl_window->impl,
- tmp_gc,
- private->impl,
- copy_rect.x-dx, copy_rect.y-dy,
- copy_rect.x, copy_rect.y,
- copy_rect.width, copy_rect.height);
- gdk_gc_set_clip_region (tmp_gc, NULL);
+ impl_iface->translate ((GdkWindow *) impl_window, dest_region, dx, dy);
}
static GdkWindowRegionMove *
GdkWindowRegionMove *move;
move = g_slice_new (GdkWindowRegionMove);
- move->dest_region = cairo_region_copy (region);
+ move->dest_region = cairo_region_copy (region);
move->dx = dx;
move->dy = dy;
* for destroying the region later.
*/
gboolean (* queue_antiexpose) (GdkWindow *window,
- cairo_region_t *update_area);
- void (* queue_translation) (GdkWindow *window,
- GdkGC *gc,
- cairo_region_t *area,
+ cairo_region_t *update_area);
+
+ /* Called to move @area inside @window by @dx x @dy pixels. @area is
+ * guaranteed to be inside @window. If part of @area is not invisible or
+ * invalid, it is this function's job to queue expose events in those
+ * areas.
+ */
+ void (* translate) (GdkWindow *window,
+ cairo_region_t *area,
gint dx,
gint dy);
#include "gdkprivate-quartz.h"
+/* FIXME: Tis function has never been compiled.
+ * Please make it work. */
void
-_gdk_quartz_window_queue_translation (GdkWindow *window,
- GdkGC *gc,
- cairo_region_t *area,
- gint dx,
- gint dy)
+_gdk_quartz_window_translate (GdkWindow *window,
+ cairo_region_t *area,
+ gint dx,
+ gint dy)
{
GdkWindowObject *private = (GdkWindowObject *)window;
GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)private->impl;
+ GdkRectangle extents;
- int i, n_rects;
- cairo_region_t *intersection;
- GdkRectangle rect;
+ cairo_region_get_extents (area, &extents);
- /* We will intersect the known region that needs display with the given
- * area. This intersection will be translated by dx, dy. For the end
- * result, we will also set that it needs display.
- */
+ [window_impl->view scrollRect:NSMakeRect (extents.x, extents.y, extents.width, extents.height)
+ by:NSMakeSize (dx, dy)];
- if (!impl->needs_display_region)
- return;
+ if (impl->needs_display_region)
+ {
+ intersection = cairo_region_copy (impl->needs_display_region);
+ cairo_region_intersect_rectangle (intersection, extents);
+ cairo_region_translate (intersection, dx, dy);
- intersection = cairo_region_copy (impl->needs_display_region);
- cairo_region_intersect (intersection, area);
- cairo_region_translate (intersection, dx, dy);
-
- _gdk_quartz_window_set_needs_display_in_region (window, intersection);
- cairo_region_destroy (intersection);
+ _gdk_quartz_window_set_needs_display_in_region (window, intersection);
+ cairo_region_destroy (intersection);
+ }
}
gboolean
iface->input_shape_combine_region = gdk_window_quartz_input_shape_combine_region;
iface->set_static_gravities = gdk_window_quartz_set_static_gravities;
iface->queue_antiexpose = _gdk_quartz_window_queue_antiexpose;
- iface->queue_translation = _gdk_quartz_window_queue_translation;
+ iface->translate = _gdk_quartz_window_translate;
iface->destroy = _gdk_quartz_window_destroy;
}
return FALSE;
}
-/*
- * queue_translation is meant to only move any outstanding invalid area
- * in the given area by dx,dy. A typical example of when its needed is an
- * app with two toplevels where one (A) overlaps the other (B). If the
- * app first moves A so that B is invalidated and then scrolls B before
- * handling the expose. The scroll operation will copy the invalid area
- * to a new position, but when the invalid area is then exposed it only
- * redraws the old areas not the place where the invalid data was copied
- * by the scroll.
- */
+/* FIXME: Tis function has never been compiled.
+ * Please make it work. */
static void
-_gdk_win32_window_queue_translation (GdkWindow *window,
- GdkGC *gc,
- cairo_region_t *area,
- gint dx,
- gint dy)
+_gdk_win32_window_translate (GdkWindow *window,
+ cairo_region_t *area,
+ gint dx,
+ gint dy)
{
HRGN hrgn = CreateRectRgn (0, 0, 0, 0);
- int ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
+ HDC hdc;
+ int ret;
+ GdkRectangle extents;
+
+ cairo_region_get_extents (area, &extents);
+ hdc = _gdk_win32_drawable_acquire_dc (GDK_DRAWABLE (window));
+ GDI_CALL (BitBlt, (hdc, extents.x, extents.y, extents.width, extents.height,
+ hdc, extents.x + dx, extents.y + dy, SRCCOPY));
+
+ /* XXX: We probably need to get invalidations for the whole extents and not
+ * just the area as we BitBlt */
+ ret = GetUpdateRgn (GDK_WINDOW_HWND (window), hrgn, FALSE);
if (ret == ERROR)
WIN32_API_FAILED ("GetUpdateRgn");
else if (ret != NULLREGION)
iface->get_deskrelative_origin = gdk_win32_window_get_deskrelative_origin;
iface->set_static_gravities = gdk_win32_window_set_static_gravities;
iface->queue_antiexpose = _gdk_win32_window_queue_antiexpose;
- iface->queue_translation = _gdk_win32_window_queue_translation;
+ iface->translate = _gdk_win32_window_translate;
iface->destroy = _gdk_win32_window_destroy;
}
}
void
-_gdk_x11_window_queue_translation (GdkWindow *window,
- GdkGC *gc,
- cairo_region_t *area,
- gint dx,
- gint dy)
+_gdk_x11_window_translate (GdkWindow *window,
+ cairo_region_t *area,
+ gint dx,
+ gint dy)
{
- GdkWindowQueueItem *item = g_new (GdkWindowQueueItem, 1);
- item->type = GDK_WINDOW_QUEUE_TRANSLATE;
- item->u.translate.area = area ? cairo_region_copy (area) : NULL;
- item->u.translate.dx = dx;
- item->u.translate.dy = dy;
+ GdkWindowQueueItem *item;
+ GdkGC *tmp_gc;
+ GdkRectangle extents;
+ GdkWindowObject *private, *impl;
+ int px, py;
+
+ /* We need to get data from subwindows here, because we might have
+ * shaped a native window over the moving region (with bg none,
+ * so the pixels are still there). In fact we might need to get data
+ * from overlapping native window that are not children of this window,
+ * so we copy from the toplevel with INCLUDE_INFERIORS.
+ */
+ private = impl = (GdkWindowObject *) window;
+ px = py = 0;
+ while (private->parent != NULL &&
+ private->parent->window_type != GDK_WINDOW_ROOT)
+ {
+ dx -= private->parent->abs_x + private->x;
+ dy -= private->parent->abs_y + private->y;
+ private = (GdkWindowObject *) _gdk_window_get_impl_window ((GdkWindow *) private->parent);
+ }
+
+ cairo_region_get_extents (area, &extents);
+
+ tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private);
+ gdk_gc_set_clip_region (tmp_gc, area);
+
+ cairo_region_translate (area, -dx, -dy); /* Move to source region */
/* Ensure that the gc is flushed so that we get the right
serial from NextRequest in gdk_window_queue, i.e. the
the serial for the XCopyArea, not the ones from flushing
the gc. */
- _gdk_x11_gc_flush (gc);
+ _gdk_x11_gc_flush (tmp_gc);
+
+ item = g_new (GdkWindowQueueItem, 1);
+ item->type = GDK_WINDOW_QUEUE_TRANSLATE;
+ item->u.translate.area = cairo_region_copy (area);
+ item->u.translate.dx = dx;
+ item->u.translate.dy = dy;
gdk_window_queue (window, item);
+
+ XCopyArea (GDK_WINDOW_XDISPLAY (impl),
+ GDK_DRAWABLE_IMPL_X11 (private->impl)->xid,
+ GDK_DRAWABLE_IMPL_X11 (impl->impl)->xid,
+ GDK_GC_GET_XGC (tmp_gc),
+ extents.x - dx, extents.y - dy,
+ extents.width, extents.height,
+ extents.x, extents.y);
+
+ gdk_gc_set_clip_region (tmp_gc, NULL);
}
gboolean
gboolean _gdk_x11_window_queue_antiexpose (GdkWindow *window,
cairo_region_t *area);
-void _gdk_x11_window_queue_translation (GdkWindow *window,
- GdkGC *gc,
+void _gdk_x11_window_translate (GdkWindow *window,
cairo_region_t *area,
gint dx,
gint dy);
iface->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
iface->set_static_gravities = gdk_window_x11_set_static_gravities;
iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
- iface->queue_translation = _gdk_x11_window_queue_translation;
+ iface->translate = _gdk_x11_window_translate;
iface->destroy = _gdk_x11_window_destroy;
iface->supports_native_bg = TRUE;
}